package com.itheima.service.serviceimpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;


import com.github.pagehelper.PageHelper;
import com.itheima.mapper.DeptMapper;
import com.itheima.mapper.EmpLogMapper;
import com.itheima.mapper.EmpMapper;
import com.itheima.mapper.ExprMapper;
import com.itheima.pojo.*;
import com.itheima.service.DeptService;
import com.itheima.service.EmpLogService;
import com.itheima.service.EmpService;
import com.itheima.utill.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class EmpServiceimpl extends ServiceImpl<EmpMapper, Emp> implements EmpService {
    @Autowired
    private EmpMapper empMapper;
    @Autowired
    private ExprMapper exprMapper;
    @Autowired
    private EmpLogMapper empLogMapper;
    @Autowired
    private EmpLogService empLogService;
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private DeptService deptService;

    //    @Override
//    public PageResult<Emp> getEmp(Integer page, Integer pageSize) {
//        //获取总记录
//        long total = empMapper.getTotal();
//        //获取索引(页码 - 1) * 每页数据
//        int index = (page - 1) * pageSize;
//        //获取分页数据
//        List<Emp> empList = empMapper.getRows(index , pageSize);
//        //封装实体类对象
//        PageResult<Emp> pageResult = new PageResult<>();
//        pageResult.setTotal(total);
//        pageResult.setRows(empList);
//        return pageResult;
//    }
    @Override
    public PageResult<Emp> getEmp(String name, Integer gender, LocalDate begin, LocalDate end, Integer page1, Integer pageSize) {
//        //设置分页参数
//        PageHelper.startPage(page1, pageSize);
//        //调用查询所有数据
//        Page<Emp> emps = (Page<Emp>) empMapper.findAll(name, gender, begin, end);
//        //封装实体类对象
//        PageResult<Emp> pageResult = new PageResult<>();
//        pageResult.setTotal(emps.getTotal());
//        pageResult.setRows(emps.getResult());
//        return pageResult;
        //设置分页的页码
        IPage<Emp> page = new Page<>(page1, pageSize);
        //查询条件
        LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(!ObjectUtils.isEmpty(name), Emp::getName, name);
        queryWrapper.eq(!ObjectUtils.isEmpty(gender), Emp::getGender, gender);
        queryWrapper.between(!ObjectUtils.isEmpty(begin) && !ObjectUtils.isEmpty(end), Emp::getEntryDate, begin, end);
        //分页查询的页码和条件
        page = super.page(page, queryWrapper);
        //这种写法中存在特定的bug与多表一起使用的时候，会出现bug
        //因为之前的所有查询到的数据集合中缺少部门名称 , 因此定义emps为完整形式
        List<Emp> emps = page.getRecords();
        //使用foreach遍历将部门名称添加进去 , 因为有一个没有部门因此还需要单独设置
        emps.forEach(emp -> {
            //根据id获取部门名称
            Dept dept = deptService.getById(emp.getDeptId());
            if (dept != null) {
                emp.setDeptName(dept.getName());
            }
        });

        //分页中的页数和数据总数
        return new PageResult<>(page.getTotal(), emps);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertEmp(Emp emp) throws Exception {
        try {
            //补全数据
            emp.setCreateTime(LocalDateTime.now());
            emp.setUpdateTime(LocalDateTime.now());
            //调用持久层
            super.save(emp);
//
//            if (true){
//                throw new Exception();
//            }

            //员工经历
            /*
             * emp对象中存在了员工的工作经历
             * 前端传输的数据有 company job begin end
             * 但是员工的工作经历表中需要有emp_id
             * 因为员工信息表和员工工作经历表是一对一的关系, 因此将员工的基本信息的主键给员工工作经历的外键中的emp_id --> 自增主键回填
             * */

            List<EmpExpr> exprList = emp.getExprList();
            if (exprList != null && exprList.size() > 0) {
                for (EmpExpr empExpr : exprList) {
                    empExpr.setEmpId(emp.getId());
                }
                exprMapper.insertExpr(exprList);
            }
        } finally {
            EmpLog empLog = new EmpLog(null, LocalDateTime.now(), "新增员工");
            empLogService.insertLog(empLog);
        }
    }

    @Override
//    @Flag
    @Transactional(rollbackFor = Exception.class)
    public void deleteEmp(List<Integer> ids) {
        //删除员工工作表
        empMapper.deleteEmp(ids);

        //删除员工工作经历
        exprMapper.deleteExpr(ids);
    }

    //查询数据回显
    @Override
//    @Flag
    public Emp queryById(Integer id) {
        //Emp emp = empMapper.getById(id);
        //return emp;e
        Emp emp = empMapper.getById(id);
        return emp;
    }

    @Override
    public void updateEmp(Emp emp) {
        //修改员工信息
        empMapper.updateEmp(emp);
        //super.updateById(emp);
        //删除工作经历
//        List<Integer> id = new ArrayList<>();
//        id.add(emp.getId());
//        exprMapper.deleteExpr(id);
        exprMapper.deleteExpr(List.of(emp.getId()));
        //添加工作经历
        List<EmpExpr> exprList = emp.getExprList();
        if (exprList != null && !exprList.isEmpty()) {
            for (EmpExpr empExpr : exprList) {
                empExpr.setEmpId(emp.getId());
            }
        }
        exprMapper.insertExpr(exprList);
    }

    /*List集合中嵌套的map集合
    {job=教研主管 , number=1},
    {job=学工主管 , number=1},
    {job=其他 , number=1},
    {job=班主任 , number=6},
    {job=咨询师 , number=7},
    {job=讲师 , number=11},
    这是两个键值对 , 分别获取到两个list集合中一个是jobList和numberList
    * */
    @Override
    public JobOption calcJobCount() {
        //因为需要封装两个数据, 并且对象只能封装一个我们需要用集合去实现这个操作, 因此用集合嵌套的方式List集合里面嵌套了一个map集合
        List<Map<String, Object>> list = empMapper.calcJobCount();
        //使用stream流分别获取他的键和值
        //职位列表
        List<Object> jobList = list.stream().map((Map<String, Object> map) -> {
            Object job = map.get("job");
            return job;
        }).collect(Collectors.toList());
        //只为数量列表
        List<Object> numberList = list.stream().map((Map<String, Object> map) -> {
            Object number = map.get("number");
            return number;
        }).collect(Collectors.toList());

        JobOption jobOption = new JobOption();
        jobOption.setJobList(jobList);
        jobOption.setDataList(numberList);
        return jobOption;
    }

    @Override
    public List<Map<String, Object>> getEmpGenderData() {
        return empMapper.getEmpGenderData();
    }

    //查询所有数据
    @Override
    public List<Emp> queryAllEmp() {
        List<Emp> list = empMapper.queryAllEmp();
        return list;
    }

    @Override
    public LoginInfo login(Emp emp) {
//        LoginInfo loginInfo = empMapper.login(emp);
//        if (loginInfo != null) {
//            //emp里有该用户
//            //创建map集合
//            Map<String, Object> map = new HashMap<>();
//            map.put("id", loginInfo.getId());
//            map.put("username", loginInfo.getUsername());
//            //获取令牌
//            String jwt = JwtUtils.generateJwt(map);
//            log.info("jwt =" + jwt);
//            loginInfo.setToken(jwt);
//            return loginInfo;
//        }
        //调用mapper接口 , 根据员工用户名和密码查找
        LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper<>();
        //获取员工的账户密码
        queryWrapper
                .eq(Emp::getUsername, emp.getUsername())
                .eq(Emp::getPassword, emp.getPassword());
        //getOne返回一个查询结果
        Emp e = super.getOne(queryWrapper);
        //获取JWT令牌 , 判断是否存在着俄国员工 , 显示登录信息
        if (e != null) {
            //e不等于null说明有这个员工
            log.info("登录成功");

            //生成JWT令牌
            Map<String, Object> map = new HashMap<>();
            map.put("id", e.getId());
            map.put("username", e.getUsername());
            String jwt = JwtUtils.generateJwt(map);
            return new LoginInfo(e.getUsername(), e.getId(), e.getName(), jwt);
        }
        //没有该用户
        return null;
    }

    @Override
    public PageResult<OperateLog> getLog(Integer page, Integer pageSize) {
        //设置分页参数
        PageHelper.startPage(page, pageSize);
        //查询所以数据
        List<OperateLog> list = empMapper.getLog();
        Page P = (Page) list;
        //创建实体类
        PageResult<OperateLog> pageResult = new PageResult<>();
        //获取total
        pageResult.setTotal(P.getTotal());
        //获取前端所需要的页面格式
        pageResult.setRows(P.getRecords());
        return pageResult;
    }
}
